home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / EtherPEG / (sources) / Promiscuity.cp < prev    next >
Encoding:
Text File  |  2000-06-24  |  7.0 KB  |  270 lines

  1. #include "EnetVersion.h"
  2. #include <stropts.h>
  3. #include <dlpi.h>
  4. #include <poll.h>
  5. #include <DriverServices.h>
  6. #define MACOS 1
  7. #include "EnetUser.h"
  8.  
  9. #include "Promiscuity.h"
  10. #include "SortFrames.h"
  11.  
  12. #define printf(...)
  13.  
  14. #define UseEndPoint 1
  15.  
  16. /******************************************************************************/
  17.  
  18. // dl_enabpromisc_req() does a DL_PROMISCON_REQ.
  19. // The stream will receive all packets.
  20. // Returns false if there was an error.
  21. static Boolean dl_enabpromisc_req(int stream)
  22. {
  23.     struct strbuf                control;
  24.     unsigned char                enabpromiscBuffer[sizeof(dl_promiscon_req_t)];
  25.     dl_promiscon_req_t *        enabpromiscReq =
  26.                                     (dl_promiscon_req_t *)enabpromiscBuffer;
  27.     unsigned char                okAckBuffer[sizeof(dl_ok_ack_t)];
  28.     dl_ok_ack_t *                okAck = (dl_ok_ack_t *)okAckBuffer;
  29.     int                            flags;
  30.     int                            err;
  31.  
  32.     // Prepare a DL_PROMISCON_REQ message.
  33.     enabpromiscReq->dl_primitive = DL_PROMISCON_REQ;
  34.     enabpromiscReq->dl_level = DL_PROMISC_PHYS;
  35.  
  36.     // Send the DL_PROMISCON_REQ message downstream to the DLPI module.
  37.     control.len = sizeof(enabpromiscBuffer);
  38.     control.buf = (char *)enabpromiscBuffer;
  39.     if (putmsg(stream, &control, NULL, 0) < 0) {
  40.         printf("dl_enabpromisc_req: putmsg errno %d\n", errno);
  41.         goto error;
  42.     }
  43.  
  44.     // Get the DL_OK_ACK message sent upstream by the DLPI module.
  45.     control.maxlen = sizeof(okAckBuffer);
  46.     control.len = 0;
  47.     control.buf = (char *)okAckBuffer;
  48.     flags = RS_HIPRI;
  49.     if (err = getmsg(stream, &control, NULL, &flags) < 0) {
  50.         printf("dl_enabpromisc_req: getmsg errno %d\n", err);
  51.         goto error;
  52.     }
  53.     if (control.len < sizeof(UInt32)) {
  54.         printf("dl_enabpromisc_req: control.len %d < %d\n",
  55.                control.len,
  56.                sizeof(UInt32));
  57.         goto error;
  58.     }
  59.     if (okAck->dl_primitive == DL_ERROR_ACK) {
  60.         printf("dl_enabpromisc_req: DL_ERROR_ACK\n");
  61.         goto error;
  62.     }
  63.     if (okAck->dl_primitive != DL_OK_ACK) {
  64.         printf("dl_enabpromisc_req: 0x%08X not DL_OK_ACK\n",
  65.                okAck->dl_primitive);
  66.         goto error;
  67.     }
  68.  
  69.     // All done, no error, return true.
  70.     return true;
  71.  
  72.     // Return false if there was an error.
  73. error:
  74.     return false;
  75.  
  76. }
  77.  
  78. /******************************************************************************/
  79.  
  80. // dl_disabpromisc_req() does a DL_PROMISCOFF_REQ.
  81. // The stream will receive all packets.
  82. // Returns false if there was an error.
  83. static Boolean dl_disabpromisc_req(int stream)
  84. {
  85.     struct strbuf                control;
  86.     unsigned char                enabpromiscBuffer[sizeof(dl_promiscon_req_t)];
  87.     dl_promiscon_req_t *        enabpromiscReq =
  88.                                     (dl_promiscon_req_t *)enabpromiscBuffer;
  89.     unsigned char                okAckBuffer[sizeof(dl_ok_ack_t)];
  90.     dl_ok_ack_t *                okAck = (dl_ok_ack_t *)okAckBuffer;
  91.     int                            flags;
  92.     int                            err;
  93.  
  94.     // Prepare a DL_PROMISCOFF_REQ message.
  95.     enabpromiscReq->dl_primitive = DL_PROMISCOFF_REQ;
  96.     enabpromiscReq->dl_level = DL_PROMISC_PHYS;
  97.  
  98.     // Send the DL_PROMISCON_REQ message downstream to the DLPI module.
  99.     control.len = sizeof(enabpromiscBuffer);
  100.     control.buf = (char *)enabpromiscBuffer;
  101.     if (putmsg(stream, &control, NULL, 0) < 0) {
  102.         printf("dl_disabpromisc_req: putmsg errno %d\n", errno);
  103.         goto error;
  104.     }
  105.  
  106.     // Get the DL_OK_ACK message sent upstream by the DLPI module.
  107.     control.maxlen = sizeof(okAckBuffer);
  108.     control.len = 0;
  109.     control.buf = (char *)okAckBuffer;
  110.     flags = RS_HIPRI;
  111.     if (err = getmsg(stream, &control, NULL, &flags) < 0) {
  112.         printf("dl_disabpromisc_req: getmsg errno %d\n", err);
  113.         goto error;
  114.     }
  115.     if (control.len < sizeof(UInt32)) {
  116.         printf("dl_disabpromisc_req: control.len %d < %d\n",
  117.                control.len,
  118.                sizeof(UInt32));
  119.         goto error;
  120.     }
  121.     if (okAck->dl_primitive == DL_ERROR_ACK) {
  122.         printf("dl_disabpromisc_req: DL_ERROR_ACK\n");
  123.         goto error;
  124.     }
  125.     if (okAck->dl_primitive != DL_OK_ACK) {
  126.         printf("dl_enabpromisc_req: 0x%08X not DL_OK_ACK\n",
  127.                okAck->dl_primitive);
  128.         goto error;
  129.     }
  130.  
  131.     // All done, no error, return true.
  132.     return true;
  133.  
  134.     // Return false if there was an error.
  135. error:
  136.     return false;
  137.  
  138. }
  139.  
  140. /******************************************************************************/
  141.  
  142. // dl_unitdata_ind() handles a DL_UNITDATA_IND.
  143. // This is the basic receive operation.
  144. // This function blocks until a packet has been received.
  145. // Returns false if there was an error.
  146. static Boolean
  147.     dl_unitdata_ind(int stream,
  148.                     UInt32 maxPacketSize,
  149.                     char *packet,
  150.                     UInt32 *packetSize,
  151.                     EnetAddressPtr address,
  152.                     Boolean block)
  153. {
  154.     struct pollfd                pfd[1];
  155.     int                            n;
  156.     struct strbuf                control;
  157.     struct strbuf                data;
  158.     int                            flags;
  159.     unsigned char        unitdataIndBuffer[sizeof(dl_unitdata_ind_t) + 26];
  160.     dl_unitdata_ind_t *    unitdataInd = (dl_unitdata_ind_t *)unitdataIndBuffer;
  161.     static int                    taskCount;
  162.  
  163.     for (;;) {
  164.         // Poll for an input message ready.
  165.         pfd[0].fd = stream;
  166.         pfd[0].events = POLLIN;
  167.         if (((n = poll(pfd, 1, block ? 1 : 0)) < 0) || (n > 1)) {
  168.             printf("WDiskServer: poll error, n = %d\n", n);
  169.             break;
  170.         }
  171.         // If timeout, do SystemTask() and check for Quit.
  172.         if (n == 0) {
  173.             if (block || ((taskCount++ & 1023) == 0)) {
  174.                 //SystemTask();
  175.             }
  176.             if (!block)
  177.                 goto error;
  178.             continue;
  179.         }
  180.         // A message is ready.  Apply getmsg().
  181.         control.maxlen = sizeof(unitdataIndBuffer);
  182.         control.len = 0;
  183.         control.buf = (char *)unitdataIndBuffer;
  184.         data.maxlen = maxPacketSize;
  185.         data.len = 0;
  186.         data.buf = packet;
  187.         flags = 0;
  188.         if ((n = getmsg(stream, &control, &data, &flags)) != 0) {
  189.             printf("WDiskServer: getmsg error, n = %d\n", n);
  190.             continue;
  191.         }
  192.         // If control length is -1, then it is a FAST-PATH message.
  193.         // Note that a FAST-PATH message does not have the source address.
  194.         if (control.len == -1)
  195.             ;
  196.         // Error if the control length is out of bounds.
  197.         else if (control.len < sizeof(UInt32)) {
  198.             printf("WDiskServer: control.len %d < %d\n",
  199.                    control.len,
  200.                    sizeof(UInt32));
  201.             continue;
  202.         }
  203.         // Error if the message is not DL_UNITDATA_IND.
  204.         else if (unitdataInd->dl_primitive != DL_UNITDATA_IND) {
  205.         //    printf("WDiskServer: dl_primitive %d != %d\n",
  206.         //           unitdataInd->dl_primitive,
  207.         //           DL_UNITDATA_IND);
  208.             continue;
  209.         }
  210.         // Process the DL_UNITDATA_IND message.
  211.         // Note that a DL_UNITDATA_IND message has the source address.
  212.         else {
  213.             BlockMove(&unitdataIndBuffer[unitdataInd->dl_src_addr_offset],
  214.                       address,
  215.                       6);
  216.         }
  217.         // Export the packet size.
  218.         *packetSize = data.len;
  219.         break;
  220.     }
  221.  
  222.     // All done, no error, return true.
  223.     return true;
  224.  
  225.     // Return false if there was an error.
  226. error:
  227.     return false;
  228.  
  229. }
  230.  
  231. /******************************************************************************/
  232.  
  233. //===
  234.  
  235. static int stream = -1;
  236.  
  237. void initPromiscuity(void)
  238. {
  239.     stream = stream_open("enet1", 0);
  240.     dl_enabpromisc_req(stream);
  241. }
  242.  
  243. void idlePromiscuity(void)
  244. {
  245.     char                        rxP[1500];
  246.     Packet                        *p = (Packet*) rxP;
  247.     UInt32                        size;
  248.     UInt8                        address[6] = {0,};
  249.  
  250.     if (dl_unitdata_ind(stream, 1500, rxP, &size, address, true))
  251.     {
  252.         if ((p->protocol == 6) && ((p->versionAndIHL & 0x0F) == 5))
  253.         {
  254.             if ((p->totalLength > 40) || (p->moreFlagsAndJunk & kFINBit))
  255.             {
  256.                 ConsumePacket( p );
  257.             }
  258.             else showBlob( 0 ); // yellow
  259.         }
  260.         else showBlob( 0 ); // yellow
  261.     }
  262. }
  263.  
  264. void termPromiscuity(void)
  265. {
  266.     dl_disabpromisc_req(stream);
  267. }
  268.  
  269.  
  270.